package com.sh.secondhand.Login;

import android.Manifest;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.*;
import butterknife.BindView;
import butterknife.ButterKnife;
import com.makeramen.roundedimageview.RoundedImageView;
import com.qiniu.android.utils.StringUtils;
import com.sh.secondhand.R;
import com.sh.struts.GlobalDefine;
import com.sh.utils.BackgroundManagerUtils;
import com.sh.utils.Http.OkHttpUtils;
import com.sh.utils.Qiniu.QiniuUploadUtils;
import com.sh.utils.UserManagerUtils;
import com.soundcloud.android.crop.Crop;
import com.zhihu.matisse.Matisse;
import com.zhihu.matisse.MimeType;
import com.zhihu.matisse.engine.impl.GlideEngine;
import com.zhihu.matisse.internal.entity.CaptureStrategy;
import permissions.dispatcher.NeedsPermission;
import permissions.dispatcher.OnNeverAskAgain;
import permissions.dispatcher.OnPermissionDenied;
import permissions.dispatcher.RuntimePermissions;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@RuntimePermissions
public class SignUpActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = "SignupActivity";
    private static final Integer REQUEST_CODE_CHOOSE = 1010;

    private UserSignUpTask mAuthTask;

    private String user_img_path = "";

    @BindView(R.id.input_name)
    EditText _nameText;
    @BindView(R.id.reinput_password)
    EditText _rePasswordText;
    @BindView(R.id.input_password)
    EditText _passwordText;
    @BindView(R.id.btn_signup)
    Button _signupButton;
    @BindView(R.id.link_login)
    TextView _loginLink;
    @BindView(R.id.signup_user_image)
    RoundedImageView user_image;
    @BindView(R.id.signup_form)
    View _signupForm;
    @BindView(R.id.signup_progress)
    ProgressBar _progressBar;

    private Intent data = new Intent();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sign_up);
        ButterKnife.bind(this);

        _signupButton.setOnClickListener(this::onClick);

        _loginLink.setOnClickListener(this::onClick);

        user_image.setOnClickListener(this::onClick);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.signup_user_image: {
                SignUpActivityPermissionsDispatcher.openMatisseWithPermissionCheck(this);
                break;
            }
            case R.id.btn_signup: {
                signup();
                break;
            }
            case R.id.link_login: {
                finish();
                break;
            }
            default:
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            if (requestCode == REQUEST_CODE_CHOOSE) {
                List<Uri> result = Matisse.obtainResult(data);
                Log.i(TAG, result.toString());
                beginCrop(result.size() == 1 ? result.get(0) : null);
            } else if (requestCode == Crop.REQUEST_CROP) {
                Uri croped = Crop.getOutput(data);
                user_image.setImageURI(croped);
                new AsyncTask<Void, Void, Void>() {
                    @Override
                    protected Void doInBackground(Void... voids) {
                        String fileName = "picture/user_img/" + System.currentTimeMillis() + ".png";
                        //测试token 正式使用的时候要替换为向服务器请求的方式
                        String token = BackgroundManagerUtils.getUploadToken();
                        if(StringUtils.isNullOrEmpty(token)){
                            showToastOnThread(SignUpActivity.this,"网络错误，上传失败");
                        }else {
                            try {
                                File file = new File(new URI(croped.toString()));
                                //七牛云上传
                                QiniuUploadUtils.getInstance().getUploadManager().put(file, fileName, token,
                                        (key, info, res) -> {
                                            //res包含hash、key等信息，具体字段取决于上传策略的设置
                                            if (info.isOK()) {
                                                user_img_path = GlobalDefine.QINIU_DOMAIN + "/" + fileName;
                                                showToastOnThread(SignUpActivity.this,"图片上传成功");
                                                Log.i("qiniu", "Upload Success");
                                            } else {
                                                showToastOnThread(SignUpActivity.this,"上传失败");
                                                Log.i("qiniu", "Upload Fail");
                                                //如果失败，这里可以把info信息上报自己的服务器，便于后面分析上传错误原因
                                            }
                                            Log.i("qiniu", key + ",\r\n " + info + ",\r\n " + res);
                                        }, null);
                                ;
                                Log.i(TAG, Crop.getOutput(data).toString());
                            } catch (URISyntaxException e) {
                                Log.e(TAG, e.getMessage());
                            }
                        }
                        return null;
                    }
                }.execute((Void)null);
            }
        }
    }

    /**
     * 在子线程里需要使用Toast
     * @param context
     * @param message
     */
    public void showToastOnThread(Context context,String message){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(context,message,Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void beginCrop(Uri source) {
        Uri destination = Uri.fromFile(new File(getCacheDir(), "cropped"));
        Crop.of(source, destination).asSquare().start(this);
    }

    /**
     * 打开Matisse的图片选择器
     */
    @NeedsPermission({Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA})
    void openMatisse() {
        Matisse.from(SignUpActivity.this)
                .choose(MimeType.ofImage()) // 选择 mime 的类型
                .capture(true)  // 开启相机，和 captureStrategy 一并使用否则报错
                .captureStrategy(new CaptureStrategy(true, "com.sh.file.FileProviderImp")) // 拍照的图片路径
                .countable(true)
                .maxSelectable(1) // 图片选择的最多数量
                .gridExpectedSize(getResources().getDimensionPixelSize(R.dimen.grid_expected_size))
                .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
                .thumbnailScale(0.85f) // 缩略图的比例
                .imageEngine(new GlideEngine()) // 使用的图片加载引擎
                .forResult(REQUEST_CODE_CHOOSE); // 设置作为标记的请求码
    }

    @OnPermissionDenied({Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA})
    void deniedOpenMatisse() {
        Toast.makeText(this, "打开失败，没有对应的权限！", Toast.LENGTH_SHORT).show();
    }

    @OnNeverAskAgain({Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA})
    void neverAskdeniedOpenMatisse() {
        Toast.makeText(this, "打开失败，请在权限管理中打开对应的权限", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        SignUpActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
    }

    public void signup() {
        Log.d(TAG, "Signup");

        if (!validate()) {
            return;
        }

        _signupButton.setEnabled(false);
        String name = _nameText.getText().toString();
        String password = _passwordText.getText().toString();
        List<OkHttpUtils.Param> params = new ArrayList<>();
        params.add(new OkHttpUtils.Param("username",name));
        params.add(new OkHttpUtils.Param("password",password));
        params.add(new OkHttpUtils.Param("pic_path",user_img_path));
        // TODO: Implement your own signup logic here.
        showProgress(true);
        mAuthTask = new UserSignUpTask(name, params);
        mAuthTask.execute((Void) null);
    }


    public void onSignupSuccess(String username) {
        _signupButton.setEnabled(true);
        setResult(RESULT_OK, data.putExtra("username",username));
        finish();
    }

    public void onSignupFailed(String msg) {
        if("repeat".equals(msg)){
            _nameText.setError("用户名已被注册！");
        }else {
            Toast.makeText(SignUpActivity.this, "注册失败", Toast.LENGTH_LONG).show();
        }

        _signupButton.setEnabled(true);
    }

    public boolean validate() {
        boolean valid = true;

        String name = _nameText.getText().toString();
        String rePassword = _rePasswordText.getText().toString();
        String password = _passwordText.getText().toString();

        if (name.isEmpty() || name.length() < 3 || name.length() > 12) {
            _nameText.setError("用户名必须是3-12个字符");
            valid = false;
        } else {
            _nameText.setError(null);
        }

        if (password.isEmpty() || password.length() < 5 || password.length() > 16){
            _passwordText.setError("密码必须由5-16位任意字符组成");
            valid = false;
        }else if(!password.equals(rePassword)){
            _rePasswordText.setError("前后两次密码必须一致！");
            valid = false;
        }else{
            _passwordText.setError(null);
            _rePasswordText.setError(null);
        }
            return valid;
    }

    /**
     * 进度显示
     * @param show
     */
    private void showProgress(boolean show){
        final ProgressDialog progressDialog = new ProgressDialog(SignUpActivity.this,
                R.style.Theme_AppCompat_DayNight_Dialog_MinWidth);
        if(show) {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
                progressDialog.setIndeterminate(true);
                progressDialog.setMessage("Creating Account...");
                progressDialog.show();
            } else {
                _signupForm.setVisibility(View.GONE);
                _progressBar.setVisibility(View.VISIBLE);
            }
        }else{
            if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
                progressDialog.dismiss();
            }else{
                _signupForm.setVisibility(View.VISIBLE);
                _progressBar.setVisibility(View.GONE);
            }
        }
    }
    /**
     * Represents an asynchronous login/registration task used to authenticate
     * the user.
     */
    public class UserSignUpTask extends AsyncTask<Void, Void, Map<String, String>> {

        private final List<OkHttpUtils.Param> params;
        private final String userName;


        UserSignUpTask(String userName,List<OkHttpUtils.Param> params) {
            this.userName = userName;
            this.params = params;
        }

        @Override
        protected Map<String, String> doInBackground(Void... params) {
            Map<String, String> signUpInfo = UserManagerUtils.userSignUp(this.params);
            return signUpInfo;
        }

        @Override
        protected void onPostExecute(final Map<String, String> resMap) {
            showProgress(false);
            if("success".equals(resMap.get("status"))){
                onSignupSuccess(this.userName);
            }else if("repeat".equals(resMap.get("status"))){
                onSignupFailed("repeat");
            }else{
                onSignupFailed(null);
            }
        }
    }
}
